/****************************************************************************
 * Copyright (c) 2010 Torkild U. Resheim
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Torkild U. Resheim  - initial API and implementation
 *****************************************************************************/
package no.resheim.buildmonitor.hudson;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;

import no.resheim.buildmonitor.core.data.Build;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Describes a particular build.
 * 
 * @author Torkild Ulvøy Resheim
 * @since 1.0
 */
public final class HudsonBuild extends Build {

	/**
	 * A time stamp indicating when this instance was last updated with fresh
	 * data
	 */
	private long lastUpdate;

	public HudsonBuild(JSONObject source) throws NumberFormatException,
			MalformedURLException, JSONException, URISyntaxException {
		super(new URI(source.getString("url")), Integer.parseInt(source
				.getString("number")), Long.parseLong(source
				.getString("timestamp")));
		decode(source);
	}

	/**
	 * Decodes a JSON object representing a build and updates the member
	 * variables of this instance with this information. If any of the member
	 * variables have changed the instance will be marked as <q>changed</q> and
	 * observers will be notified.
	 * 
	 * @param source
	 *            the JSON object to decode
	 * @throws NumberFormatException
	 * @throws JSONException
	 * @throws URISyntaxException
	 * @throws MalformedURLException
	 */
	void decode(JSONObject source) throws NumberFormatException, JSONException,
			URISyntaxException {
		lastUpdate = System.currentTimeMillis();
		setDuration(Long.parseLong(source.getString("duration")));
		setBuilding(Boolean.parseBoolean(source.getString("building")));
		// Notify observers that we have changed
		if (hasChanged()) {
			notifyObservers();
		}
	}

	/**
	 * Returns <code>true</code> if this instance's data may be outdated. We're
	 * postulating that it has to be older than ten seconds for this to be the
	 * case.
	 * 
	 * @return <code>true</code> if the data may be old
	 */
	boolean mayBeOld() {
		return (lastUpdate + 10000) < System.currentTimeMillis();
	}
}
